// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: Implementation of CElementWithValueAndXBL.
//   $Id$

#include "stdafx.h"
#include "elementwithvalueandxbl.h"
#include "XFormsXFormsElement.h"
#include "UIImplRepository.h"

CElementWithValueAndXBL::CElementWithValueAndXBL(void)
{
}

CElementWithValueAndXBL::~CElementWithValueAndXBL(void)
{
}



//At DocumentReady, fetch a UI Engine and attach it.
HRESULT CElementWithValueAndXBL::DocumentReady()
{
	HRESULT hr = __super::DocumentReady();
	hr = getUI(&m_pEngine);
	if(m_pEngine)
	{
		CComQIPtr<IEngine2> pEngine2 = m_pEngine;
	/*
		//This doesn't work:  IE doesn't actually import the namespaces until this 
		// function has returned, so when the Attach occurs, no additional namespace
		// prefixes are used in resolving behaviours for new nodes.

		if(pEngine2)
		{
			CComPtr<IXMLDOMNodeList> pNl;
			pEngine2->get_activeNamespaces(&pNl);
			m_pFormControl->m_pXForms->importAdditionalNamespacePrefixes(pNl);
		}
	*/	CComPtr<IHTMLElement> pEl;
		hr = GetMasterElement(&pEl);

		if(pEl)
		{
			CComQIPtr<IDispatchEx> pDispEx(pEl);
			hr =m_pEngine->Attach(pDispEx);
		}
	}
	return hr;
}


HRESULT CElementWithValueAndXBL::getUI(IEngine ** ppEngine)
{
	HRESULT hr = E_FAIL;
	
	//First see if it has an xbl-binding attribute 
	//	which can be used to retrieve a node from an 
	//	xml data island in the master document.
	
	//TODO: reenable this when refactoring with CElementWithXBL
	//	it has only been disabled to expedite the production of
	//	demo which uses the feature that inspired the implementation
	//	of this class.

	hr = S_FALSE;//GetLocallySpecifiedBinding(ppEngine);
	if(S_FALSE == hr)
	{
	
		//Then use the standard transformation method.
		CComPtr<IXMLDOMNode> pNode;
		hr = getXML(&pNode);

		if(pNode && m_pXForms) 
		{
			//get the xblEngine
			CUIImplRepository * pRepository = m_pXForms->GetUIImplRepository();
			
			try
			{
				hr = pRepository->GetUIImpl(pNode,ppEngine);
				if(!*ppEngine)
				{
					CComBSTR sTagsXML;
					pNode->get_xml(&sTagsXML);
					//ATLTRACE2("'formsplayer.dll': No UI handler loaded for %S\n",sTagsXML);
				}
			} 
			catch(...) 
			{
				CComPtr<IErrorInfo> pErr;
				::GetErrorInfo(0,&pErr);
				CComBSTR sDescription;
				if(pErr)
					pErr->GetDescription(&sDescription);
				CString s;
				CComBSTR sTagsXML;
				pNode->get_xml(&sTagsXML);
				s.Format("'formsplayer.dll': error %S in resolving UI for:\n %S\n",sDescription,sTagsXML);
				::MessageBox(0,s,0,0);
			}

		}
	}

	return hr;
}


STDMETHODIMP CElementWithValueAndXBL::Detach()
{
	HRESULT hr = __super::Detach();
	if(m_pEngine)
		m_pEngine->Detach();
	return hr;
}